#include "task.hpp"

struct picture
{
    std::string frame;
    float fps = 0.0;
};

BlockQueue<picture>* bq = new BlockQueue<picture>;

void http_task(int fd, std::string& inbuffer, std::string& outbuffer)
{
    // 只处理第一次请求，后续保持连接发送视频流
    outbuffer = "HTTP/1.1 200 OK\r\n"
                "Server: OpenMV\r\n"
                "Content-Type: multipart/x-mixed-replace; boundary=openmv\r\n"
                "Connection: keep-alive\r\n"
                "Cache-Control: no-cache\r\n"
                "Pragma: no-cache\r\n"
                "\r\n";
    send(fd, outbuffer.c_str(), outbuffer.size(), 0);
    outbuffer.clear();
    // 持续发送视频帧
    while (true)
    {
        picture pic = bq->pop();
        std::string header = 
            "--openmv\r\n"
            "Content-Type: image/jpeg\r\n"
            "Content-Length: " + std::to_string(pic.frame.size()) + "\r\n\r\n";
        outbuffer = header + pic.frame;
        if (send(fd, outbuffer.c_str(), outbuffer.size(), MSG_NOSIGNAL) < 0)
        {
            log(Log::Warning, "write error, sockfd: %d, clientip: %s, clientport: %d, errstring: %s", fd, strerror(errno));
            break;
        }
        usleep(int(1000000 / pic.fps) + 8000);
    }
}

void device_task(int fd, std::string& inbuffer, std::string& outbuffer)
{
    // 查找报头
    size_t header_begin = inbuffer.find("Content-Length:");
    if (header_begin == std::string::npos)
        return;
    if (header_begin > 0)
        inbuffer.erase(0, header_begin);
    size_t header_end = inbuffer.find("\r\n\r\n");
    if (header_end == std::string::npos)
        return;
    
    std::string header = inbuffer.substr(0, header_end + 2);
    std::vector<std::string> header_lines;
    size_t pos = 0;
    size_t prev = 0;
    
    // 分割报头行
    while ((pos = header.find("\r\n", prev)) != std::string::npos)
    {
        header_lines.push_back(header.substr(prev, pos - prev));
        prev = pos + 2;
    }
    
    picture pic;
    int length = 0;
    
    // 解析报头行
    for (const auto& line : header_lines)
    {
        if (line.find("Content-Length:") == 0)
        {
            // 提取内容长度
            std::string len_str = line.substr(15);
            // 去除前导空白字符
            len_str.erase(0, len_str.find_first_not_of(" \t"));
            length = std::stoi(len_str);
        }
        else if (line.find("tick:") == 0)
        {
            // 提取FPS值
            std::string fps_str = line.substr(5);
            // 去除前导空白字符
            fps_str.erase(0, fps_str.find_first_not_of(" \t"));
            pic.fps = std::stof(fps_str);
        }
    }
    
    size_t body_begin = header_end + 4;
    if (inbuffer.size() < body_begin + length)
        return;
    
    pic.frame = inbuffer.substr(body_begin, length);
    
    // 将数据放入队列
    if (bq->full())
        bq->pop();
    bq->push(pic);
    
    inbuffer.erase(0, body_begin + length);
}
